package com.xiaotu.spider.guduo.pageprocessor;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.model.TVGuDuoArticleModel;
import com.xiaotu.common.model.TVGuDuoPlayModel;
import com.xiaotu.common.util.Constants;
import com.xiaotu.common.util.HttpUtils;
import com.xiaotu.common.util.KeywordEncode;
import com.xiaotu.common.util.PageUtils;
import com.xiaotu.common.util.RegexUtils;
import com.xiaotu.common.util.SepratorUtil;
import com.xiaotu.common.util.StringUtil;
import com.xiaotu.common.util.TVProcessUtils;
import com.xiaotu.spider.APageProcessor;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.selector.Html;

/**
 * @类名 GuDuoPageProcessor
 * @日期 2017年11月20日
 * @作者 王艳龙
 * @功能 骨朵传媒数据爬取
 */
@Component("GuDuoPageProcessor")
@Scope("prototype")
public class GuDuoPageProcessor extends APageProcessor{

	@Override
	protected Request getStartRequest(JSONObject target) {
		return new Request("http://data.guduomedia.com/search/list?keyword="
                + KeywordEncode.encode(target.getString("tvName")));
	}

	@Override
	public String getPageDataType(Page page) {
		String url = page.getUrl().toString();
		if (url.contains("http://data.guduomedia.com/search/list"))
			return Constants.PageDataType.SEARCH_LIST;
		else if (url.contains("http://data.guduomedia.com/show/detail"))
			return Constants.PageDataType.TV_RECORD;
		return Constants.PageDataType.UNKNOW;
	}
	
	@Override
	public void process(Page page) {
		Map<String, Object> tvInfoMap = page.getRequest().getExtras();
        String dataType = this.getPageDataType(page);

        switch (dataType)
        {
            case Constants.PageDataType.SEARCH_LIST:
                this.searchListProcess(page, tvInfoMap);
                break;
            case Constants.PageDataType.TV_RECORD:
                this.tvRecordProcess(page, tvInfoMap);
                break;
            default:
                break;
        }
		
	}

	 private void searchListProcess(Page page,final Map<String, Object> tvInfoMap){
		 	List<String> tvnameList = new ArrayList<String>();
	        List<String> linkList = new ArrayList<String>();
	        List<String> tvTypes = new ArrayList<String>();
	        List<List<String>> directors = new ArrayList<List<String>>();
	        List<List<String>> actors = new ArrayList<List<String>>();
	        List<String> directorList = new ArrayList<String>();
	        List<String> actorList = new ArrayList<String>();
	        //搜索页面
	        final List<String> searchListHTML = page.getHtml()
	                .xpath("//div[@class='result']//div[@class='box']").all();
	        if(searchListHTML.isEmpty())
	        	 throw new SpiderException(
		                    SpiderExceptionCode.DataInvalideException);
	        
	        String showIds =page.getHtml().xpath("//div[@class='result']//div[@class='box']//a[@class='clearfix']/@href").get();
	        String showId = showIds.substring(showIds.indexOf("showId=")+7);
	        for (String htmlStr : searchListHTML)
	        {
	            Html html = new Html(htmlStr);
	            List<String> descList = html.xpath("//div[@class='desc-box']/span").all();
	            String director ="";
	            
	            for (String  dir_act: descList) {
					if(!dir_act.isEmpty() && dir_act.contains("导演:")){
						director= dir_act.substring(dir_act.indexOf("<em>")+4, dir_act.indexOf("</em>"));
						if(director.contains(" ") && !director.contains("/")){
							director = director.trim().replaceAll(RegexUtils.REGEX_NOT_CH, ",");
						}else if(director.contains(" ") && director.contains("/")){
							director = director.replace(" ", "");
							director = director.trim().replaceAll(RegexUtils.REGEX_NOT_CH, ",");
						}else{
							director = director.replace(" ", "");
							director = director.trim().replaceAll(RegexUtils.REGEX_NOT_CH, ",");
						}
						String[] directorArr = director.split(SepratorUtil.SEP_COMMA_EN);
						for (String stringStr : directorArr) {
							directorList.add(stringStr);
						}
						directors.add(directorList);
					}else if(!dir_act.isEmpty() && dir_act.contains("主演:")){
						String actor = dir_act.substring(dir_act.indexOf("<em>")+4, dir_act.indexOf("</em>"));
						if(actor.contains(" ") && !actor.contains("/")){
							actor = actor.trim().replaceAll(RegexUtils.REGEX_NOT_CH, ",");
						}else if(actor.contains(" ") && actor.contains("/")){
							actor = actor.replace(" ", "");
							actor = actor.trim().replaceAll(RegexUtils.REGEX_NOT_CH, ",");
						}else{
							actor = actor.replace(" ", "");
							actor = actor.trim().replaceAll(RegexUtils.REGEX_NOT_CH, ",");
						}
						
						String[] actorArr = actor.split(SepratorUtil.SEP_COMMA_EN);
						for (String stringStr : actorArr) {
							actorList.add(stringStr);
						}
						actors.add(actorList);
					}
				}

	            if (StringUtil.isEmpty(director))
	                continue;

	            tvnameList.add(html
	                    .xpath("//div[@class='right-box']//div[@class='clearfix']/h2/text()")
	                    .toString().trim());
	            linkList.add(html
	                    .xpath("//div[@class='box']//a[@class='clearfix']/@href")
	                    .toString());
	            String tvtype = html
	                    .xpath("//div[@class='right-box']//div[@class='clearfix']/span/text()")
	                    .toString().trim();
	            if(tvtype.contains("院线")){
	            	tvtype = tvtype.replace("院线", "");
	            }
	            tvTypes.add(tvtype);
	        }

	        if (linkList.size() != tvnameList.size()
	                //|| linkList.size() != tvTypes.size()
	                || linkList.size() != directors.size()
	                || linkList.size() != actors.size())
	            throw new SpiderException(
	                    SpiderExceptionCode.DataInvalideException);
	        
	        
	        TVProcessUtils.addTVFromSearchList(page, tvInfoMap, tvnameList,
	        		linkList, tvTypes, actors, directors,
	        		new TVProcessUtils.TVMatcher()
	        {
	        	@Override
	        	protected boolean addTV(Page page,
	        			Map<String, Object> tvinfoMap, String name,
	        			String tvType, List<String> actorsList,
	        			List<String> directorsList, String link, int idx)
	        	{
	        		if (TVProcessUtils.tvMatched(tvinfoMap, name,
	        				TVProcessUtils.getTVType(tvType), actorsList,
	        				directorsList))
	        		{
	        			tvInfoMap.put("showId", showId);
	        			PageUtils.addTargetRequest(page,
	        					"http://data.guduomedia.com/show/detail?showId="+showId,
	        							tvInfoMap, true);
	        			return true;
	        		}
	        		return false;
	        	}
	        }, null);
	 }
	 
	 private void tvRecordProcess(Page page, Map<String, Object> tvInfoMap){
		 //获取播放量
		 String playCount = HttpUtils
	                .httpGetJSONP("http://data.guduomedia.com/playcount/review/"
	                        + tvInfoMap.get("showId"));
	        if (StringUtils.isEmpty(playCount))
	            return;
	     JSONObject playCountObject = JSONObject.fromObject(playCount);
	     //今日播放量
	     String todayPlayCount =playCountObject.getString("today_play_count");
	     //昨日播放量
	     String ydayPlayCount =playCountObject.getString("yesterday_play_count");
	     //累计播放量
	     String totalPlayCount =playCountObject.getString("total_play_count");
	     //上映天数
	     String releaseDays =playCountObject.getString("release_days");
	     
	     String[] playRateName = null;
	     String[] playRateCount = null;
	     //获取播放平台分布值
	     String rateJson = HttpUtils
	                .httpGetJSONP("http://data.guduomedia.com/playcount/day/"+tvInfoMap.get("showId")+"?day=1");
	     JSONObject resultJson = new JSONObject().fromObject(rateJson);
	     if(resultJson.size()!=0){
	    	String ratename =resultJson.getString("names");
	    	String ratecount =resultJson.getString("clicks");
	    	if(StringUtils.isNotEmpty(ratename)&& StringUtil.isNotEmpty(ratecount)){
	    		ratename = ratename.replace("[","").replace("]", "").replace("\"", "");
	    		if(ratename.contains("PP视频")){
	    			ratename=ratename.replace("PP视频", "PPTV聚力");
	    		}
	    		ratecount = ratecount.replace("[","").replace("]", "");
	    		String[] resulStr =ratename.split(","); 
	    		playRateName =new String[resulStr.length];
	    		playRateCount = new String[resulStr.length];
	    		for (int i = 0; i < resulStr.length; i++) {
	    			playRateName[i]=resulStr[i];
	    			playRateCount[i]=ratecount.split(",")[i];
	    		}
	    	}	 
	     }
	     /*String rateJson = HttpUtils
	                .httpGetJSONP("http://data.guduomedia.com/playcount/platform/"
	                        + tvInfoMap.get("showId"));
        JSONObject my = new JSONObject().fromObject(rateJson);
		 Iterator keys = my.keys();
		 if(my.size()!=0){
			 int i = 0;
			 playRateName = new String[my.size()];
			 playRateCount = new String[my.size()];
			 while (keys.hasNext()) {
				 String key = (String) keys.next();
				 String value = my.getString(key);
				 if(key.contains("code")||key.contains("message")||key.contains("url")||key.contains("data")){
					 playRateName = new String[]{};
					 playRateCount = new String[]{};
				 }else{
					 playRateName[i]=key;
					 playRateCount[i]=value;
					 i++;
				 }
			 }
		 }*/
	     
		 String[] danmuBoxName = null;
		 String[] danmuBoxCount = null;
	     //获取弹幕词云
		 String danmuJson = HttpUtils
	                .httpGetJSONP("http://data.guduomedia.com/barrage/wordcloud/"
	                        + tvInfoMap.get("showId")+"/random");
		 if (!danmuJson.equals("[]")){
			 JSONArray infoArr = JSONArray.fromObject(danmuJson);
			 LinkedList<Object> nameList = new LinkedList<>();
			 LinkedList<Object> valueList = new LinkedList<>();
			 if (null != infoArr && infoArr.size() > 0) {
				 for (Iterator<Object> iterator = infoArr.iterator(); iterator.hasNext();) { 
					 JSONObject jsonObject = (JSONObject) iterator.next(); 
					 jsonObject.get("name");
					 nameList.add(jsonObject.get("name"));
					 valueList.add(""+jsonObject.get("value")+"");
				 }
			 }
			 
			 danmuBoxName = nameList.toArray(new String[0]);
			 danmuBoxCount = valueList.toArray(new String[0]);
		 }
		 page.putField(TVGuDuoPlayModel.class.getName(), new TVGuDuoPlayModel((String) tvInfoMap.get("tvid"),(String) tvInfoMap.get("tvName"),
				 todayPlayCount,ydayPlayCount, totalPlayCount, releaseDays,playRateName,playRateCount, danmuBoxName, danmuBoxCount));
	    	
	     
	    //获取文章微博数据
		 String articleJson = HttpUtils
	                .httpGetJSONP("http://data.guduomedia.com/media/overview/"
	                        + tvInfoMap.get("showId"));
	     
	     JSONObject articleJsonObject = new JSONObject().fromObject(articleJson);
	     
	     String wechatArticleCount = null;
	     String weiboTopicCount = null;
	     String doubanScore = null;
	     String doubanScoreCount = null;
	     String newsCount = null;
	     String ydayCommentCount = null;
	     String totalCommentCount = null;
	     String ydayPostCount = null;
	     if(articleJson.contains("wechat_article_count")){
	    	 //昨日微信文章数
	    	 wechatArticleCount =articleJsonObject.getString("wechat_article_count");
	     }
	     if(articleJson.contains("weibo_hot_count")){
	    	 //昨日相关微博话题数
	    	 weiboTopicCount = articleJsonObject.getString("weibo_hot_count");
	     }
	     if(articleJson.contains("douban_score")){
	    	 //豆瓣评分
	    	 doubanScore = articleJsonObject.getString("douban_score");
	    	 if(doubanScore.contains("0.0")){
	    		 doubanScore = doubanScore.replace(".0", "");
	    	 }
	     }
	     if(articleJson.contains("douban_judges_count")){
	    	 //豆瓣评分人数
	    	 doubanScoreCount = articleJsonObject.getString("douban_judges_count");
	     }
	     if(articleJson.contains("news_count")){
	    	 //昨日新闻收录量
	    	 newsCount= articleJsonObject.getString("news_count");
	     }
	     if(articleJson.contains("yestoday_comment")){
	    	 //昨日评论数
	    	 ydayCommentCount = articleJsonObject.getString("yestoday_comment");
	     }
	     if(articleJson.contains("total_comment_count")){
	    	 //总评论数
	    	 totalCommentCount = articleJsonObject.getString("total_comment_count");
	     }
	     if(articleJson.contains("tieba_post_inc")){
	    	 //昨日新增帖子数
	    	 ydayPostCount= articleJsonObject.getString("tieba_post_inc");
	     }
	     //微博热门话题名
	     String[] weiboHotName = null;
	     //微博热门阅读数量
	     String[] weiboHotCount = null;
	     if(articleJson.contains("weibo_tags")){
	    	 articleJson = articleJson.substring(articleJson.indexOf("weibo_tags\":")+12, articleJson.length()-1);
	    	 JSONArray weiboArr = JSONArray.fromObject(articleJson);
	    	 LinkedList<Object> weiboNameList = new LinkedList<>();
	    	 LinkedList<Object> weiboValueList = new LinkedList<>();
	    	 if (null != weiboArr && weiboArr.size() > 0) {
	    		 for (Iterator<Object> iterator = weiboArr.iterator(); iterator.hasNext();) { 
	    			 JSONObject jsonObject = (JSONObject) iterator.next(); 
	    			 jsonObject.get("keyword");
	    			 weiboNameList.add(jsonObject.get("keyword"));
	    			 weiboValueList.add(""+jsonObject.get("read_count")+"");
	    		 }
	    	 }
	    	 weiboHotName = weiboNameList.toArray(new String[0]);
	    	 weiboHotCount = weiboValueList.toArray(new String[0]);
	     }
    	
    	page.putField(TVGuDuoArticleModel.class.getName(), new TVGuDuoArticleModel((String) tvInfoMap.get("tvid"),(String) tvInfoMap.get("tvName"),
    			wechatArticleCount=="null"?"0":wechatArticleCount,  weiboTopicCount==null?"0":weiboTopicCount, weiboHotName,weiboHotCount, 
    			doubanScore==""?"0":doubanScore, doubanScoreCount==""?"0":doubanScoreCount, newsCount==null?"0":newsCount,
				ydayCommentCount==null?"0":ydayCommentCount, totalCommentCount==null?"0":totalCommentCount, ydayPostCount==null?"0":ydayPostCount));
	 }
	
	@Override
	protected String getSpiderType() {
		return Constants.SpiderTaskType.TV_GUDUO;
	}
}
